import Filesystem from "../Filesystem";
import { sha1 } from "../Support/Str";
import { join } from 'path'

export default abstract class Compiler
{
    /**
     * The Filesystem instance.
     */
    protected files: Filesystem;

    /**
     * Get the cache path for the compiled views.
     */
    protected cachePath: string;

    /**
     * Create a new compiler instance.
     *
     * @param  {Filesystem}  files
     * @param  {string}  cachePath
     * @return {void}
     *
     * @throws {Error}
     */
    public constructor(files: Filesystem, cachePath: string)
    {
        if (!cachePath) {
            throw new Error('Please provide a valid cache path.');
        }

        this.files = files;
        this.cachePath = cachePath;
    }

    /**
     * Get the path to the compiled version of a view.
     *
     * @param  {string}  path
     * @return {string}
     */
    public getCompiledPath(path: string)
    {
        return join(this.cachePath,sha1(path) + '.js');
    }

    /**
     * Determine if the view at the given path is expired.
     *
     * @param  {string}  path
     * @return {bool}
     */
    public async isExpired(path: string)
    {
        let compiled = this.getCompiledPath(path);

        // If the compiled file doesn't exist we will indicate that the view is expired
        // so that it can be re-compiled. Else, we will verify the last modification
        // of the views is less than the modification times of the compiled views.
        const fileExists = await this.files.exists(compiled)
        if (! fileExists) {
            return true;
        }

        return Promise.all([this.files.lastModified(path), 
               this.files.lastModified(compiled)]).then(([a, b]) => a >= b);
    }
}